<?php

namespace App\Kuafu\Common\Service;

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Redis;

class TencentMapKeysConfigService
{

    private static ?TencentMapKeysConfigService $instance = null;

    /**
     * 所有keys
     * @var array
     */
    public array $allKeys;

    /**
     * @var \Redis
     */
    public \Redis $redisClient;

    private function __construct()
    {
        $this->redisClient = Redis::connection()->client();
        $this->allKeys     = ConfigService::getTencentMapConfig();
    }

    /**
     * @return TencentMapKeysConfigService|null
     */
    public static function getInstance(): ?TencentMapKeysConfigService
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 获取有效的keys
     *
     * @return array
     */
    public function getEffectiveKeys(): array
    {
        return array_diff($this->allKeys, array_intersect($this->allKeys, $this->getLoseEffectiveKeys()));
    }

    /**
     * 获取已失效的keys
     *
     * @return mixed|null
     */
    public function getLoseEffectiveKeys()
    {
        return jsonToArr($this->redisClient->get($this->loseEffectiveKeysCacheKey()), []);
    }

    /**
     * 设置已失效的keys
     *
     * @param string $key
     */
    public function setLoseEffectiveKeys(string $key)
    {
        $value = collect([$key]);
        if (!$this->redisClient->setnx($this->loseEffectiveKeysCacheKey(), $value->toJson(JSON_UNESCAPED_UNICODE))) {
            $value = $value->merge(jsonToArr($this->redisClient->get($this->loseEffectiveKeysCacheKey())))->unique();
            $this->redisClient->set($this->loseEffectiveKeysCacheKey(), $value->toJson(JSON_UNESCAPED_UNICODE));
        }

        $this->redisClient->expire(
            $this->loseEffectiveKeysCacheKey(),
            Carbon::now()->endOfDay()->timestamp - time()
        );
    }

    /**
     * @return string
     */
    private function loseEffectiveKeysCacheKey(): string
    {
        return "tencentMap:loseEffectiveKeys";
    }

    /**
     * 随机获取有效key
     * @return array|int|string
     */
    public function getRandEffectiveKey()
    {
        $effectiveKeys = $this->getEffectiveKeys();
        return $effectiveKeys ? $effectiveKeys[array_rand($effectiveKeys)] : "";
    }
}
